/*
 *
 * Copyright (C) 2011-2020 ShenZhen iBOXCHAIN Information Technology Co.,Ltd.
 * All right reserved.
 * This software is the confidential and proprietary
 * information of iBOXCHAIN Company of China.
 * ("Confidential Information"). You shall not disclose
 * such Confidential Information and shall use it only
 * in accordance with the terms of the contract agreement
 * you entered into with iBOXCHAIN inc.
 *
 */

package com.example.mybaseapp.util.match;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Shader;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
import android.widget.EditText;
import android.widget.TextView;

import androidx.annotation.ColorInt;
import androidx.annotation.ColorRes;
import androidx.appcompat.widget.AppCompatEditText;

import java.text.DecimalFormat;
import java.util.regex.Pattern;

/**
 * @Description: 字符串工具类
 * @Author: Seal
 * @CreateDate: 2020/7/9 12:39
 * @Version: 1.0
 */
public class StringUtil {

    private StringUtil() {
        throw new UnsupportedOperationException("u can't instantiate me...");
    }

    /**
     * 判断字符串是否为null或长度为0
     *
     * @param s 待校验字符串
     * @return {@code true}: 空<br> {@code false}: 不为空
     */
    public static boolean isEmpty(final CharSequence s) {
        return s == null || s.length() == 0;
    }


    public static String getFriendlyDistanceStr(float distance) {
        DecimalFormat format = new DecimalFormat(".00");
        if (distance >= 1000f) {
            float kD = distance / 1000;
            return format.format(kD) + "km";
        } else {
            return format.format(distance) + "m";
        }
    }

    /**
     * 判断字符串是否为null或全为空格
     *
     * @param s 待校验字符串
     * @return {@code true}: null或全空格<br> {@code false}: 不为null且不全空格
     */
    public static boolean isTrimEmpty(final String s) {
        return (s == null || s.trim().length() == 0);
    }

    /**
     * 判断字符串是否为null或全为空白字符
     *
     * @param s 待校验字符串
     * @return {@code true}: null或全空白字符<br> {@code false}: 不为null且不全空白字符
     */
    public static boolean isSpace(final String s) {
        if (s == null) return true;
        for (int i = 0, len = s.length(); i < len; ++i) {
            if (!Character.isWhitespace(s.charAt(i))) {
                return false;
            }
        }
        return true;
    }

    /**
     * 判断两字符串是否相等
     *
     * @param a 待校验字符串a
     * @param b 待校验字符串b
     * @return {@code true}: 相等<br>{@code false}: 不相等
     */
    public static boolean equals(final CharSequence a, final CharSequence b) {
        if (a == b) return true;
        int length;
        if (a != null && b != null && (length = a.length()) == b.length()) {
            if (a instanceof String && b instanceof String) {
                return a.equals(b);
            } else {
                for (int i = 0; i < length; i++) {
                    if (a.charAt(i) != b.charAt(i)) return false;
                }
                return true;
            }
        }
        return false;
    }

    /**
     * 判断两字符串忽略大小写是否相等
     *
     * @param a 待校验字符串a
     * @param b 待校验字符串b
     * @return {@code true}: 相等<br>{@code false}: 不相等
     */
    public static boolean equalsIgnoreCase(final String a, final String b) {
        return a == null ? b == null : a.equalsIgnoreCase(b);
    }

    /**
     * null转为长度为0的字符串
     *
     * @param s 待转字符串
     * @return s为null转为长度为0字符串，否则不改变
     */
    public static String null2Length0(final String s) {
        return s == null ? "" : s;
    }

    /**
     * 返回字符串长度
     *
     * @param s 字符串
     * @return null返回0，其他返回自身长度
     */
    public static int length(final CharSequence s) {
        return s == null ? 0 : s.length();
    }

    /**
     * 首字母大写
     *
     * @param s 待转字符串
     * @return 首字母大写字符串
     */
    public static String upperFirstLetter(final String s) {
        if (isEmpty(s) || !Character.isLowerCase(s.charAt(0))) return s;
        return String.valueOf((char) (s.charAt(0) - 32)) + s.substring(1);
    }

    /**
     * 首字母小写
     *
     * @param s 待转字符串
     * @return 首字母小写字符串
     */
    public static String lowerFirstLetter(final String s) {
        if (isEmpty(s) || !Character.isUpperCase(s.charAt(0))) return s;
        return String.valueOf((char) (s.charAt(0) + 32)) + s.substring(1);
    }

    public static boolean isUrl(String s) {
        if (isTrimEmpty(s)) return false;
        String pattern = "(https?|ftp|file)://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]";
        return Pattern.matches(pattern, s);
    }

    /**
     * 反转字符串
     *
     * @param s 待反转字符串
     * @return 反转字符串
     */
    public static String reverse(final String s) {
        int len = length(s);
        if (len <= 1) return s;
        int mid = len >> 1;
        char[] chars = s.toCharArray();
        char c;
        for (int i = 0; i < mid; ++i) {
            c = chars[i];
            chars[i] = chars[len - i - 1];
            chars[len - i - 1] = c;
        }
        return new String(chars);
    }

    /**
     * 转化为半角字符
     *
     * @param s 待转字符串
     * @return 半角字符串
     */
    public static String toDBC(final String s) {
        if (isEmpty(s)) return s;
        char[] chars = s.toCharArray();
        for (int i = 0, len = chars.length; i < len; i++) {
            if (chars[i] == 12288) {
                chars[i] = ' ';
            } else if (65281 <= chars[i] && chars[i] <= 65374) {
                chars[i] = (char) (chars[i] - 65248);
            } else {
                chars[i] = chars[i];
            }
        }
        return new String(chars);
    }

    /**
     * 转化为全角字符
     *
     * @param s 待转字符串
     * @return 全角字符串
     */
    public static String toSBC(final String s) {
        if (isEmpty(s)) return s;
        char[] chars = s.toCharArray();
        for (int i = 0, len = chars.length; i < len; i++) {
            if (chars[i] == ' ') {
                chars[i] = (char) 12288;
            } else if (33 <= chars[i] && chars[i] <= 126) {
                chars[i] = (char) (chars[i] + 65248);
            } else {
                chars[i] = chars[i];
            }
        }
        return new String(chars);
    }

    /**
     * 判断两个字符串的相似度
     *
     * @param str1
     * @param str2
     */
    public static void levenshtein(String str1, String str2) {
        //计算两个字符串的长度。
        int len1 = str1.length();
        int len2 = str2.length();
        //建立上面说的数组，比字符长度大一个空间
        int[][] dif = new int[len1 + 1][len2 + 1];
        //赋初值，步骤B。
        for (int a = 0; a <= len1; a++) {
            dif[a][0] = a;
        }
        for (int a = 0; a <= len2; a++) {
            dif[0][a] = a;
        }
        //计算两个字符是否一样，计算左上的值
        int temp;
        for (int i = 1; i <= len1; i++) {
            for (int j = 1; j <= len2; j++) {
                if (str1.charAt(i - 1) == str2.charAt(j - 1)) {
                    temp = 0;
                } else {
                    temp = 1;
                }
                //取三个值中最小的
                dif[i][j] = min(dif[i - 1][j - 1] + temp, dif[i][j - 1] + 1,
                        dif[i - 1][j] + 1);
            }
        }
        System.out.println("字符串\"" + str1 + "\"与\"" + str2 + "\"的比较");
        //取数组右下角的值，同样不同位置代表不同字符串的比较
        System.out.println("差异步骤：" + dif[len1][len2]);
        //计算相似度
        float similarity = 1 - (float) dif[len1][len2] / Math.max(str1.length(), str2.length());
        System.out.println("相似度：" + similarity);
    }

    //得到最小值
    private static int min(int... is) {
        int min = Integer.MAX_VALUE;
        for (int i : is) {
            if (min > i) {
                min = i;
            }
        }
        return min;
    }

    /**
     * 获取屏幕上可见文本【排除掉已读的内容】
     *
     * @param textView
     * @param readContent 已读内容
     * @return 返回“” 表示已读内容超过了当前显示的内容区域
     */
    public static String getNumberOfWordsDisplayed(TextView textView, String readContent) {
        Layout layout = textView.getLayout();
        if(layout == null) return "";
        int start = layout.getLineStart(getFirstLineIndex(textView));
        if(!TextUtils.isEmpty(readContent) && readContent.length() - start > 150) {
             start = readContent.length() - 15;
        }

        int end = layout.getLineEnd(getLastLineIndex(textView));
        try {
            return textView.getText().toString().substring(start, end);
        }catch (StringIndexOutOfBoundsException e){
            return "";
        }
    }

    /**
     * 获取从start到end的文字内容
     * @param textView
     * @param start
     * @param end
     * @return
     */
    public static String getNumberOfWordsDisplayed(TextView textView, int start, int end){
        Layout layout = textView.getLayout();
        if(layout==null) return "";
        return textView.getText().toString().substring(start, end);
    }

    /**
     * 获取可见区域文字的开始位置
     * @param textView
     * @return
     */
    public static int getNumberOfWordsDisplayedStartIndex(TextView textView) {
        Layout layout = textView.getLayout();
        if(layout == null) return 0;
        int start = layout.getLineStart(getFirstLineIndex(textView));

       return start;
    }
    /**
     * 获取可见区域文字的结束位置
     * @param textView
     * @return
     */
    public static int getNumberOfWordsDisplayedEndIndex(TextView textView) {
        Layout layout = textView.getLayout();
        if(layout == null) return 0;

        int end = layout.getLineEnd(getLastLineIndex(textView));
        return end;
    }

    /**
     * 获取TextView当前显示的内容
     * @param atx
     * @return
     */
    public static String getTextViewShowContent(TextView atx){
        Layout layout = atx.getLayout();
        int scrollY = atx.getScrollY();
//                    获取当前可见的第一行的开始位置
        int firstVisibleLineNumber = layout.getLineForVertical(scrollY);

        // 获取当前可见的最后一行的结束位置
        int lastVisibleLineNumber = layout.getLineForVertical(atx.getScrollY() + atx.getHeight())-1;
        return atx.getText().toString().substring(firstVisibleLineNumber,lastVisibleLineNumber);
    }



    /**
     * Gets the first line that is visible on the screen.
     *
     * @return
     */
    public static int getFirstLineIndex(TextView textView) {
        int scrollY = textView.getScrollY();
        Layout layout = textView.getLayout();
        if (layout != null) {
            return layout.getLineForVertical(scrollY);
        }
        return -1;
    }

    /**
     * Gets the last visible line number on the screen.
     *
     * @return last line that is visible on the screen.
     */
    public static int getLastLineIndex(TextView textView) {
        int height = textView.getHeight();
        int scrollY = textView.getScrollY();
        Layout layout = textView.getLayout();
        if (layout != null) {
            return layout.getLineForVertical(scrollY + height)-1;
        }
        return -1;
    }

    /**
     * 模糊匹配
     *
     * @param mainTxt
     * @param blueTxt
     * @param threshold
     * @return
     */
    public static Object[] getBlurMatchStr(String mainTxt, String blueTxt, float threshold) {
        DiffMatchUtil dmp = new DiffMatchUtil();
        dmp.Match_Distance = 1000;//设置
        dmp.Match_Threshold = threshold;
        long s1 = System.currentTimeMillis();
        int match = dmp.match_main(mainTxt, blueTxt, 0);//这里内部实际就是调用match_bitap方法，没有其他操作
//        int match = dmp.match_bitap(mainTxt, blueTxt, blueTxt.length());//模糊匹配，找到匹配文字的位置
        long s2 = System.currentTimeMillis();
        if (match == -1) return new Object[]{"-", match, (s2-s1)};
        //匹配到的文字，将前面的文字全部算进去
        int resultMatch = match + blueTxt.length();
        if(resultMatch >= mainTxt.length()) return new Object[]{"null", match, (s2-s1)};
        String s = mainTxt.substring(match, resultMatch);
        return new Object[]{s, match, (s2-s1)};
    }

    /**
     * 获取当前位置与顶部的距离
     * @param textView
     * @param index
     * @return
     */
    public static int getTextViewSelectionTopY(TextView textView, int index, String text) {
        Layout layout = textView.getLayout();
        Rect bound = new Rect();
        int line = layout.getLineForOffset(index);//当前所在行
        layout.getLineBounds(line, bound);
        return bound.top;
////        int yAxisBottom = bound.bottom;//字符底部y坐标
//        int yAxisTop = bound.top;//字符顶部y坐标
////        float xAxisLeft = layout.getPrimaryHorizontal(index);//字符左边x坐标
////        float textSize = textView.getTextSize();//每个字符的大小
////        Log.d("StringUtil", "getTextViewSelectionTopY: "+textSize);
//        int distance =  yAxisTop;
////        int distance = textSize >= 40? yAxisBottom : yAxisTop;
////        float layoutWidth = layout.getWidth();//屏幕的宽度
////        float countTextLength = xAxisLeft + text.length() * textSize;//计算出来字符右边的x坐标
////        int lastLine = getLastLineIndex(textView);//最后一行
////        int toButtomLine =lastLine - line;//当前行数离底部行数
////        if(toButtomLine > 0 && toButtomLine <= 3){ //离底部太近了，可以翻了
////            return distance;
////        }else if(layoutWidth < countTextLength){//换行了
////            return distance;
////        }
////        else if(layoutWidth > countTextLength){
////            if(layoutWidth - countTextLength < 50) {//这行差不多读完了可以翻了
////                return distance;
////            }else{//这行没读完，不用翻
////                return 0;
////            }
////        }
//        return distance;
    }

    /**
     * 获取此位置当前行数
     */
    public static int getLineForOffset(TextView textView, int index){
        Layout layout = textView.getLayout();
        if(layout == null) return 0;
        int line = layout.getLineForOffset(index);//当前所在行
        return line;
    }


}